<?php
namespace Ysian\Tools\file;

use Ysian\Tools\http\Http;

class File
{
    /**
     * @desc  远程文件下载
     * @param $url 远程地址
     * @param string $filename 保存的文件名称
     * @param string $save_dir 文件保存目录
     * @return string
     * @throws \Exception
     */
    public static function download($url,$filename='',$save_dir = './')
    {
        //检测文件是否存在
        self::isExist($url);

        if (trim($save_dir)=='') $save_dir = './';
        if (trim($filename)=='') {
            $ext = strrchr($url,'.');
            $filename = time().$ext;
        }




        if (strrpos($save_dir,'/')==0)  $save_dir .= '/';
        if (!file_exists($save_dir) && !mkdir($save_dir,0777,true)) {
            throw new \Exception('文件目录不存在');
        }

        //获取文件资源
        $file = Http::curl_get($url);

        $resource = fopen($save_dir . $filename, 'a');
        fwrite($resource, $file);
        fclose($resource);
        unset($file);
        return $save_dir.$filename;
    }

    /**
     * @desc 检测文件是否存在并返回类型, remote远程文件  local服务器文件
     * @param $file 文件路径或者url地址
     * @return string 'remote' or 'local'
     * @throws \Exception
     */
    public static function isExist($file)
    {
        // 远程文件,包括http和https
        if (strtolower(substr($file, 0, 4)) == 'http'){
            $header = get_headers($file, true);
            if (!isset($header[0]) || !( strpos($header[0], '200') || strpos($header[0], '304')) ){
                throw new \Exception('远程文件不存在');
            }
            return 'remote';
        } else {
            // 本地文件
            if(!file_exists($file)){
                throw new \Exception('文件不存在');
            }
            return 'local';
        }
    }

    /**
     * @desc 文件压缩
     * @param $file_arr  文件集合
     * @param string $save_dir 保存的目录
     * @param string $zip_name 保存的文件名
     * @return string 返回压缩后的文件路径
     */
    public static function zip($file_arr,$save_dir = './',$zip_name='')
    {
        if (trim($save_dir)=='') $save_dir = './';
        if (trim($zip_name)=='') {
            $zipName = time() . '.zip'; // 压缩包文件名
        }
        if (strrpos($save_dir,'/')==0)  $save_dir .= '/';
        $zipNameUrl = $save_dir . $zipName; // 文件路径

        // 生成文件
        $zip = new \ZipArchive();
        if ($zip->open($zipNameUrl, \ZipArchive::OVERWRITE) !== true) {
            //OVERWRITE 参数会覆写压缩包的文件 文件必须已经存在
            if ($zip->open($zipNameUrl, \ZipArchive::CREATE) !== true) {
                // 文件不存在则生成一个新的文件 用CREATE打开文件会追加内容至zip
                throw new \Exception('文件夹不存在');
            }
        }

        foreach ($file_arr as $file) {
            //判断图片是否存在
            try{
                self::isExist($file);
                //抓取图片内容
                $fileContent = file_get_contents($file);
                $name = self::getName($file);
                //添加图片
                $zip->addFromString($name, $fileContent);
            } catch (\Exception $e){
                //文件不存在,则跳过
                continue;
            }
        }
        // 关闭
        $zip->close();
        return $zipNameUrl;
    }

    /**
     * @desc 获取文件的名称及后缀
     * @param $file
     * @return false|mixed
     */
    public static function getName($file)
    {
        $file_name = explode('/',$file);
        return end($file_name);
    }

    /**
     * @desc 浏览器文件下载 远程图片请保证其具有下载属性,如果不具有请先下载到服务器,浏览器下载完成后选择是否删除服务器上的该资源
     * @param $file 文件路径以及后缀
     * @param string $name 要保存的文件名称(要带后缀哦)
     * @param false $del 是否删除
     */
    public static function browser_down($file,$name='',$del=false)
    {
        $type = self::isExist($file);
        if($type=='remote') {
            header('Location: '.$file);exit;
        } else {
            if(!trim($name)) $name = self::getName($file);
            header("Cache-Control: public");
            header("Content-Description: File Transfer");
            header('Content-disposition: attachment; filename=' . $name); //文件名
            header("Content-Type: application/zip"); //zip格式的
            header("Content-Transfer-Encoding: binary"); //告诉浏览器，这是二进制文件
            header('Content-Length: ' . filesize($file)); //告诉浏览器，文件大小

            // 下面2步必须要
            ob_clean();
            flush();

            @readfile($file);
            if($del==true){
                unlink($file); // 删除文件
            }
            exit;
        }
    }
}